package com.uxwine.alarm;


import com.uxwine.alarm.alert.RingManager;
import com.uxwine.alarm.db.TBAlram;

import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;

public class AlarmDao
{
    
	/**
     * Queries all alarms
     * @return cursor over all alarms
     */
    public static Cursor getAlarmsCursor(ContentResolver cr) 
    {
        return cr.query(TBAlram.CONTENT_URI, 
        		TBAlram.QUERY_COLUMNS,
                null, null, TBAlram.DEFAULT_SORT_ORDER);
    }
    
    /**
     * Return an Alarm object representing the alarm id in the database.
     * Returns null if no alarm exists.
     */
    public static Alarm getAlarm(ContentResolver contentResolver, int alarmId) 
    {
        Cursor cursor = contentResolver.query(
                ContentUris.withAppendedId(TBAlram.CONTENT_URI, alarmId),
                TBAlram.QUERY_COLUMNS,
                null, null, null);
        if (cursor == null) 
        	return null;
        Alarm alarm = null;
        if (cursor.moveToFirst()) 
        {
            alarm = new Alarm(cursor);
        }
        cursor.close();
        return alarm;
    }
    
    // Private method to get a more limited set of alarms from the database.
    public static Cursor getEnabledAlarm(ContentResolver cr) 
    {
        return cr.query(TBAlram.CONTENT_URI,
        		TBAlram.QUERY_COLUMNS, 
        		TBAlram.WHERE_ENABLED,
                null, null);
    }
    
    public static void enableAlarm(final Context context,
            final Alarm alarm, boolean enabled) 
    {
        if (alarm == null) 
        {
            return;
        }
        ContentResolver resolver = context.getContentResolver();

        ContentValues values = new ContentValues(2);
        values.put(Alarm.Columns.ENABLED, enabled ? 1 : 0);
        
        if (enabled) 
        {
        	long time = 0;
        	if(!alarm.cycle.isRepeatSet())
        	{
        		time = calculateAlarm(alarm);
        	}
            values.put(Alarm.Columns.TRIGGER, time);
        }
        resolver.update(
        		ContentUris.withAppendedId(TBAlram.CONTENT_URI, alarm.id),
        		values, null, null);
    }
    
    /**
     * Creates a new Alarm and fills in the given alarm's id.
     */
    public static long addAlarm(Context context, Alarm alarm) {
    	
        ContentValues values = createContentValues(alarm);
        Uri uri = context.getContentResolver().insert(TBAlram.CONTENT_URI, values);
        alarm.id = (int) ContentUris.parseId(uri);
        
        return calculateAlarm(alarm);
    }
    
    /**
     * A convenience method to set an alarm in the Alarms
     * content provider.
     * @return Time when the alarm will fire.
     */
    public static long setAlarm(Context context, Alarm alarm) {
        ContentValues values = createContentValues(alarm);
        ContentResolver resolver = context.getContentResolver();
        resolver.update(
                ContentUris.withAppendedId(TBAlram.CONTENT_URI, alarm.id),
                values, null, null);
        return calculateAlarm(alarm);
    }
    
    /**
     * Removes an existing Alarm.  If this alarm is snoozing, disables
     * snooze.  Sets next alert.
     */
    public static void deleteAlarm(Context context, int alarmId) {
        if (alarmId == -1) return;

        ContentResolver contentResolver = context.getContentResolver();

        Uri uri = ContentUris.withAppendedId(TBAlram.CONTENT_URI, alarmId);
        contentResolver.delete(uri, "", null);
    }
    
    protected static ContentValues createContentValues(Alarm alarm) {
        ContentValues values = new ContentValues(8);
        // Set the alarm_time value if this alarm does not repeat. This will be
        // used later to disable expire alarms.
        long time = 0;
        if (!alarm.cycle.isRepeatSet()) 
        {
            time = calculateAlarm(alarm);
        }

        values.put(Alarm.Columns.ENABLED, alarm.enabled ? 1 : 0);
        values.put(Alarm.Columns.TIME, alarm.time.toString());
        values.put(Alarm.Columns.TRIGGER, alarm.trigger);
        values.put(Alarm.Columns.CYCLE, alarm.cycle.getCycle());
        values.put(Alarm.Columns.CYCLE_FLAGS, alarm.cycle.getFlags());
        values.put(Alarm.Columns.VIBRATE, alarm.vibrate);
        values.put(Alarm.Columns.LABEL, alarm.label);

        // A null alert Uri indicates a silent alarm.
        values.put(Alarm.Columns.ALERT, alarm.alert == null ? 
        		RingManager.RING_SILENT : alarm.alert.toString());
        return values;
    }
    
    protected static long calculateAlarm(Alarm alarm) 
    {
        return AlarmCalc.triggerTime(alarm);
    }   
}
